/*******************************************************
> Copyright (C) 2024 ==IOT== All rights reserved.
> File Name: 1.c
> Author: wyf
> Website:www.lv1.org
> Created Time: 2024年08月05日 星期一 16时23分43秒
***************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf
{
	long mtype;
	char mtext[50];
};
typedef struct stu{
	int id;
	char name[20];
	int age;
	struct stu *Next;
}STU;
//函数声明
STU* List_init();
STU* Create_list(STU *head);
void Printf_list(STU *head);
void Send_list(STU *head, int msgid);
int main(int argc, const char* argv[])
{
	STU *head = NULL;
	printf("头结点  初始化成功\n");
	head = List_init();
	head =Create_list(head);	
	printf("你输入的链表数据是:\n");
	Printf_list(head);
	key_t key = 0;
	int msgid = 0;
	int ret = 0;
	key = ftok("./",1);
		if(key == -1)
		{
				perror("ftok");
				exit(-1);
		}
	msgid = msgget(key,IPC_CREAT|0666);
		if(msgid == -1)
	{
		perror("msgget");
		exit(-1);
	}
	struct msgbuf msg;
	memset(&msg,0,sizeof(struct msgbuf));
	msg.mtype = 1;

	
	
//----------------------------------------------------------------------先写-----------------------------------------	
	
	// 发送链表到队列中
	Send_list(head, msgid);
	
//----------------------------------------------------------再接收读进程读完队列返回的话-----------------------------
	struct msgbuf data;
	memset(&data,0,sizeof(data));
	ret = msgrcv(msgid,&data,sizeof(struct msgbuf) - sizeof(long),2,0);
	if(ret == -1)
	{
		perror("msgrcv");
		exit(-1);
	}

	printf("\nB进程返回的话： %s\n",data.mtext);
//----------------------------------------------------------A进程最后再销毁队列-----------------------------------------------------
    		
	ret = msgctl(msgid,IPC_RMID,NULL);
	printf("已销毁队列\n");
	if(ret == -1)
	{
		perror("msgctl");
		exit(-1);
	}
	
	return 0;
}



// 发送链表
void Send_list(STU *head, int msgid) {
    STU* p = head->Next;
    struct msgbuf msg;
    int ret;
	//发送链表到队列
    while (p != NULL) {
        msg.mtype = 1;
        memcpy(msg.mtext, p, sizeof(STU));//写入结构体大小,必须是.mtext

        ret = msgsnd(msgid, &msg, sizeof(msg.mtext)-sizeof(long), 0);//上传结构体
        if (ret == -1) {
            perror("msgsnd");
            exit(-1);
        }
        p = p->Next;//遍历
    }
	
	// 再单独发送完成标志
    msg.mtype = 1;
    memset(msg.mtext, 0, sizeof(msg.mtext));
    strcpy(msg.mtext, "END");
    ret = msgsnd(msgid, &msg, sizeof(msg.mtext), 0);
    if (ret == -1) {
        perror("msgsnd");
        exit(-1);
    }


    printf("链表数据发送完成！\n");
}







STU* List_init(){
	STU *p = malloc(sizeof(STU));
	memset(p,0,sizeof(STU));
	p->Next = NULL;
	printf("\n");
	return p;
}
//新建链表
STU* Create_list(STU *head){
	assert(head != NULL);
	STU* p = head;
	STU* newnode = NULL;
	int temp = 0;
	int flag = 0;
	while(flag == 0){
	newnode = (STU*)malloc(sizeof(STU));
	memset(newnode,0,sizeof(STU));
	printf("请输入id:\n");
	scanf("%d",&(newnode->id));

	printf("请输入姓名name:\n");
	scanf("%s",newnode->name);

	printf("请输入年龄age:\n");
	scanf("%d",&(newnode->age));

	p->Next = newnode;
	newnode->Next = NULL;
	p = newnode;
	printf("继续输入吗？(1是退出):\n");
	scanf("%d",&temp);
	if(temp == 1){

			flag = 1;
		}

	}
	printf("数据插入成功！\n");
	printf("\n");
	return head;				//操作是p指针，返回必须是头结点

}

//打印输出的链表
void Printf_list(STU *head){
	assert(head != NULL);
	STU* p = head->Next;
	while(p != NULL){
		printf("编号：%d 姓名: %s 年龄: %d\n",p->id,p->name,p->age);
		p = p->Next;
	}
}
